<?php

namespace App\Modules\LuckDraw\LuckDraw;

use App\Http\Model\User;
use App\Modules\LuckDraw\Exp\ExpFactory;
use App\Modules\LuckDraw\Lib\StrLib;
use App\Modules\LuckDraw\Message\MessageFactory;
use App\Modules\LuckDraw\Models\AwardPoolModel;
use App\Modules\LuckDraw\Models\LuckDrawModel;
use App\Modules\LuckDraw\Strategy\StrategyFactory;
use App\Modules\LuckDraw\User\LuckUser;
use App\Modules\LuckDraw\UserTag\UserTagFactory;

class LuckDrawFactory {
    private static $instances = [];
    //获取一个抽奖实例
    public static function get($luckId, ?object $user = null, ?int $roomId = 0) : ?LuckDrawInterface{
        if (empty($luckId)) {
            return null;
        }

        //默认房间id = 0
        if (empty($roomId)) {
            $roomId = 0;
        }

        if (isset(self::$instances[$luckId])) {
            return self::$instances[$luckId];
        }
        
        //默认当前用户id = 11
        if (empty($user)) {
            $user = (new User())->get_user(11);
            $user = (object)$user;
        }
        //从数据库获取配置
        $luckDrawModel = LuckDrawModel::get($luckId);
        if ($luckDrawModel == null) {
            return null;
        }

        //用户标签名字（标签就是把用户分类的根据，不如注册，就是根据用户的注册时间分类，
        //消费标签就是根据用户的消费量去分类，通过给用户分类可以采用不同的抽奖策略）
        $tagName = $luckDrawModel->tag;
        //策略配置数据 （在该用户标签下，使用的策略配置数据）
        $strategyPoolData = json_decode($luckDrawModel->strategy_pool);
        //获取用户标签的实例
        $userTagInstance = UserTagFactory::get($luckId, $user->user_id, $tagName, $strategyPoolData);
        //根据用户标签获取使用的具体策略数据（比如策略名，扩展数据等），以及奖池id
        list($strategyData, $poolId) = $userTagInstance->getStrategyPool();
        
        //获取奖池数据
        $pool = AwardPoolModel::get($poolId);

        //获取策略实例
        $strategyInstance = StrategyFactory::get($luckId, $user->user_id, $strategyData, $pool);

        //获取抽奖用户实例
        $luckUserInstance = LuckUser::instance($luckId, $roomId, $user);

        //获取抽奖活动的实例
        $luckDrawClassName = self::getClassName($luckDrawModel->en_name);
        if ($luckDrawClassName == null) {
            return null;
        }

        //获取经验值实例，用来增加获取经验值
        $expInstance = ExpFactory::get($luckDrawModel->exp_id);

        //获取消息 用于发送消息
        $messageInstance = MessageFactory::get($luckDrawModel->msg_id);

        $luckDrawInstance = new $luckDrawClassName(
            $luckDrawModel,
            $strategyInstance,
            $userTagInstance,
            $luckUserInstance,
            $expInstance,
            $messageInstance
        );
        self::$instances[$luckId] = $luckDrawInstance;
        return $luckDrawInstance;
    }

    private static function getClassName(string $luckDrawName):?string{
        if (empty($luckDrawName)){
            return null;
        }
        $className = __NAMESPACE__ . '\\' . StrLib::camelize($luckDrawName) . 'LuckDraw';
        if(class_exists($className)){
            return $className;
        }
        return null;
    }
}